<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
namespace app\common\library\amap;

use app\common\exception\BaseException;
use app\common\library\helper;

/**
 * 商家信息同步
 * Class WxPay
 * @package app\common\library\wechat
 */
class WxShop extends WxBase {
	// 微信支付配置
	private $config;

	// 当前商城ID
	private $storeId;

	/**
	 * 构造函数
	 * @param array $config
	 * @param int|null $storeId
	 */
	public function __construct(array $config = [], ?int $storeId = null) {
		parent::__construct();
		$this->config = $config;
		$this->storeId = $storeId;

	}

	/**
	 * 统一下单API
	 * @param $orderNo
	 * @param $openid
	 * @param $totalFee
	 * @param int $orderType 订单类型
	 * @return array
	 * @throws \cores\exception\BaseException
	 */
	public function updateShop($method, $biz_content): array {

		// 生成随机字符串
		//$nonceStr = md5($time . $openid);
		// API参数

		$params['method'] = $method;
		$params['app_id'] = '202409070191916319';
		$params['charset'] = 'UTF-8';
		$params['utc_timestamp'] = time() * 1000;
		$params['version'] = '1.0';
        $params['biz_content'] =json_encode($biz_content);
		
		// 生成签名
		$params['sign'] = $this->makeSign($params);
        $params['sign_type'] = 'RSA2';

		// 请求API
		$url = 'https://restapi.amap.com/rest/openmp/devgw?key=b9bbf58608fe017bf4951db2e868f94d';
		$result = $this->post($url, $params);

		print_r($result);exit;
		$prepay = $this->fromXml($result);
		// 请求失败
		if ($prepay['return_code'] === 'FAIL') {
			$errMsg = "微信支付api：{$prepay['return_msg']}";
			throwError($errMsg, null, ['errorCode' => 'WECHAT_PAY', 'isCreated' => true]);
		}
		if ($prepay['result_code'] === 'FAIL') {
			$errMsg = "微信支付api：{$prepay['err_code_des']}";
			throwError($errMsg, null, ['errorCode' => 'WECHAT_PAY', 'isCreated' => true]);
		}
		// 生成 nonce_str 供前端使用
		$paySign = $this->makePaySign($params['nonce_str'], $prepay['prepay_id'], $time);
		return [
			'prepay_id' => $prepay['prepay_id'],
			'nonceStr' => $nonceStr,
			'timeStamp' => (string) $time,
			'paySign' => $paySign,
		];
	}

	/**
	 * 返回状态给微信服务器
	 * @param boolean $returnCode
	 * @param string|null $msg
	 */
	private function returnCode(bool $returnCode = true, string $msg = null) {
		// 返回状态
		$return = [
			'return_code' => $returnCode ? 'SUCCESS' : 'FAIL',
			'return_msg' => $msg ?: 'OK',
		];
		// 记录日志
		log_record([
			'name' => '返回微信支付状态',
			'data' => $return,
		]);
		die($this->toXml($return));
	}

	/**
	 * 生成paySign
	 * @param string $nonceStr
	 * @param string $prepayId
	 * @param int $timeStamp
	 * @return string
	 */
	private function makePaySign(string $nonceStr, string $prepayId, int $timeStamp): string {
		$data = [
			'appId' => $this->appId,
			'nonceStr' => $nonceStr,
			'package' => 'prepay_id=' . $prepayId,
			'signType' => 'MD5',
			'timeStamp' => $timeStamp,
		];
		// 签名步骤一：按字典序排序参数
		ksort($data);
		$string = $this->toUrlParams($data);
		// 签名步骤二：在string后加入KEY
		$string = $string . '&key=' . $this->config['apikey'];
		// 签名步骤三：MD5加密
		$string = md5($string);
		// 签名步骤四：所有字符转为大写
		return strtoupper($string);
	}

	/**
	 * 将xml转为array
	 * @param string $xml
	 * @return mixed
	 */
	private function fromXml(string $xml) {
		// 禁止引用外部xml实体
		libxml_disable_entity_loader(true);
		return helper::jsonDecode(helper::jsonEncode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)));
	}

	/**
	 * 生成签名
	 * @param array $values
	 * @return string 本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
	 */
	private function makeSign(array $values): string {
		//签名步骤一：按字典序排序参数
		ksort($values);
		$content = $this->toUrlParams($values);
		//签名步骤二：在string后加入KEY
		//$string = $string . '&key=' . $this->config['apikey'];
		$priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGwA6Qc9LtBoBmTaD38u1ZzwPJC6l4vIImDiX+crTTZK9od6hxTEkEZn2TGnl3l1e8qj4fUz43dQlnjwLZUCcu1yjF7wy4hehTWtD13sRmQQ/b7qQlT2sHsnypS9C9EqkXwqf6eXkvzXA5gw7CTYW+3/m/eumV1T9y8aGKrPsWjTphtuvjPB1k7SAuC1HH7mSipk66DQmzBeiGenMQSLdU+yGAIhlEjunXQmyyJv+EABPZWEsAVw7MvzH2Glk8cIfN7Z0qB9HGrnOpP191RrFjRRJjdKA/i/wtDlV1ByXUnDfFkF7D234N0zAW2pUqajW27RvYTz2DRzF3oVpJe1vlAgMBAAECggEAJbZ+3QLtl5ToPrmfQYXl0+rSXmQ7LCVmL4xqKcqkvT1CsnQ62mrFTMv6fT89m7Dpx03GUTIVCaRh22/1FikOrldde/gpkUM5AIs8THPqd8vhymYB3sdZZzAXH7KuWxxr4tCB/uIcfrp6nD4H1W2o7wD0fxjBY0PpnBvwYEWFiIvaM4wDBfVtB5mZcWVeYCCqLDWqH//TRI+G4I6pFv8aOY3TybAgOa+g65aNcMw0CrCrE70mAMO2FMdRtIhquSCsYkitkCisIHBJlH8pRrfa42kUKA774G49tQ6kIvySNYCq/BF7z+bkz63cTE6P+xDj5topZ5aFxyE6lZUv52NeyQKBgQDACyQ4BpXuLGWe+kLA/WclqKYTR+vQwLCFOc4m/70yQsaLDri5pJfSVVXvIm3pOcM7sKOpVP9T93Kqy41Whraqro4DGIcLbdoK+Co1E0UGGe3Ew/vVxMtuysp2L15j2KxdMgvLuZnHaZMg6/tXMo4hP6X4lX7mtA+sZLn/HzkmbwKBgQCzoFGuyC6PED2S26W7ZSE+Z/TsHmNjmAxfXMkxcHulxvnr5Q+TPZkYvyWPdqIaITGultn0zHPpRn+3NVoT6UqwVcNebqYl01a9UPbTfO2FRxu9mSzdlLXqQ4bgj7STnilLT5islwuiSMQ0bjBUFNKFEy1Xb5bKBAQpctHXbjYs6wKBgQCKNrqPc/XuH5fXrifi+72Dtfgowkduy29/wtWi7cX96V85b5P1UAdQgshBPlc6Vq8zQ3LWiOzmQp4NXEhRsMzA1LYydjGjQSF/aZH+9upjdL/SMHcMKAF9sIe8PWVCmQucW0twCRkrEsmoFQ6keCcguM07tmRJp+fr2+adPZyFEwKBgFcRc+aLw/22upHwBBKkv4t3aoH1bOm+ruiemitrwZOmskgE3Rra9dXH+ZXjxEl0I5fkKTv+yoSdlpSguMwD/h8hQzUH32NgYKAdmbcDzEIZKLorgFLbnZ4zIzLAlaAkPxHxQCkQgiQkr25Wpvhqq2yz0fua7HV5oubQcCTDmGEHAoGACBp8YnVK/8nIAmFw49zmkCUSFQf3xTJ7qOiH01JQUl9OQw++vZD55JbdkXEuFQ7/eQCBg18M/g/mtQ0geWSHWKGC9XsLiF9F2rs3Atv3NiD2g8Xm2+qUmY6cAuFdS+yjX46VuHrs5XJLSfOKz/VhqEQ9wWqJN5Bo4oZXw8HAZo4=";

		
		$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
		wordwrap($priKey, 64, "\n", true) .
			"\n-----END RSA PRIVATE KEY-----";
		($res) or die('您使用的私钥格式错误，请检查RSA私钥配置');
    $key = openssl_get_privatekey($res);
		openssl_sign($content, $sign, $key, OPENSSL_ALGO_SHA256);
		$sign = base64_encode($sign);

		return $sign;
	}

	/**
	 * 格式化参数格式化成url参数
	 * @param array $values
	 * @return string
	 */
	private function toUrlParams(array $values): string {
		$buff = '';
		foreach ($values as $k => $v) {
			if ($k != 'sign' && $v != '' && !is_array($v)) {
				$buff .= $k . '=' . $v . '&';
			}
		}
		return trim($buff, '&');
	}

	/**
	 * 输出xml字符
	 * @param array $values
	 * @return bool|string
	 */
	private function toXml(array $values) {
		if (!is_array($values)
			|| count($values) <= 0
		) {
			return false;
		}
		$xml = "<xml>";
		foreach ($values as $key => $val) {
			if (is_numeric($val)) {
				$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
			} else {
				$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
			}
		}
		$xml .= "</xml>";
		return $xml;
	}
}
